﻿using Singbon.Utility;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

//已经上传至gitee https://gitee.com/zghnzch/SingbonICCardRestartSingbon.git
namespace RestartSingbon {

    public partial class TimeToRestart : Form {
        private Config cfg = Config.Instance;

        public int isListening = 0;
        private Process[] pros = null;
        private Thread t = null;
        public string SingbonICCardLocation = "";
        public int startCount = 0;
        private int alreadyStartCount = 0;

        public TimeToRestart() {
            InitializeComponent();
            cfg.LoadConfig();
        }

        private void Form1_Load(object sender, EventArgs e) {
            startCount=0;
            cfg.openSystemRestart="0";
            cfg.alsoOpenMonitor="0";
            cfg.SaveConfig();
            SingbonICCardLocation=System.Windows.Forms.Application.StartupPath;
            Console.WriteLine("系统路径  "+SingbonICCardLocation+" "+cfg.SysPwd);
            if(cbx_isListening.Checked) {
                cbx_isListening.Text="当前状态：启用";
            } else {
                cbx_isListening.Text="当前状态：停用";
            }
            if(cbx_alsoOpenMonitor.Checked) {
                cbx_alsoOpenMonitor.Text="当前状态：启用";
            } else {
                cbx_alsoOpenMonitor.Text="当前状态：停用";
            }
            txt_ExeName.Text="SingbonICCard";
        }

        #region 主线程

        private void ListenSingbon() {
            while(isListening==1) {
                pros=Process.GetProcessesByName("SingbonICCard");
                Console.WriteLine("***********************************************************");
                Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff")+" 进程信息 "+pros+" IsFixedSize "+pros.IsFixedSize);
                if(null!=pros&&isListening==1&&pros.IsFixedSize&&pros.Length>0) {//程序已经启动
                    for(int i = 0;i<pros.Length;i++) {
                        this.Invoke(new MethodInvoker(delegate () {
                            lbl_sysAlreadyStartTimeCount.Text="启动时长";
                            lbl_sysIsStarted.Text="是否启动";
                            lbl_startTime.Text="启动时间";
                            lbl_isResponds.Text="是否响应";
                            lbl_proThreadCount.Text="进程线程个数";
                            lbl_proLocation.Text="进程所在目录";

                        }));
                        //Console.WriteLine("进程名称：" + i + " " + pros[i].ProcessName);
                        //Console.WriteLine("进程个数：" + pros.Length);
                        //Console.WriteLine("进程所在目录：" + pros[i].MainModule.FileName);
                        //Console.WriteLine("进程线程个数：" + pros[i].Threads.Count);
                        //Console.WriteLine("进程ID：" + pros[i].Id.ToString());
                        //Console.WriteLine("启动时间：" + pros[i].StartTime.ToLongDateString() + pros[i].StartTime.ToLongTimeString());
                        //Console.WriteLine("启动时间2：" + pros[i].StartTime);
                        //Console.WriteLine("启动时间3：" + pros[i].StartTime.ToString("yyyy-MM-dd HH:mm:ss:fff"));
                        //Console.WriteLine("是否响应：" + pros[i].Responding.ToString());
                        //Console.WriteLine("关联进程句柄：" + pros[i].Handle.ToString());
                        //Console.WriteLine("进程打开的句柄数：" + pros[i].HandleCount.ToString());
                        //Console.WriteLine("主窗口句柄：" + pros[i].MainWindowHandle.ToString());
                        //Console.WriteLine("主窗口标题：" + pros[i].MainWindowTitle);
                        //Console.WriteLine("模块数量：" + pros[i].Modules.Count.ToString());
                        //Console.WriteLine("基本优先级：" + pros[i].BasePriority.ToString());
                        //Console.WriteLine("提升优先级：" + pros[i].PriorityBoostEnabled.ToString());
                        //Console.WriteLine("处理器：" + pros[i].ProcessorAffinity.ToInt32().ToString());
                        //Console.WriteLine("最小工作集：" + pros[i].MinWorkingSet.ToInt32().ToString());
                        //Console.WriteLine("最大工作集：" + pros[i].MaxWorkingSet.ToInt32().ToString());
                        /*****************************************************************/
                        //判断是否需要关闭程序
                        DateTime time1 = pros[i].StartTime;
                        DateTime time2 = DateTime.Now;
                        TimeSpan ts = time2.Subtract(time1);
                        alreadyStartCount=ts.Days*24*60*60+ts.Hours*60*60+ts.Minutes*60+ts.Seconds;
                        this.Invoke(new MethodInvoker(delegate () {
                            //lbl_sysAlreadyStartTimeCount.Text = lbl_sysAlreadyStartTimeCount.Text + ":" + alreadyStartCount.ToString()+"秒";
                            lbl_sysAlreadyStartTimeCount.Text=lbl_sysAlreadyStartTimeCount.Text+":"+ts.Days+"天"+ts.Hours+"时"+ts.Minutes+"分"+ts.Seconds+"秒"+"（"+alreadyStartCount.ToString()+"秒）";
                            lbl_sysIsStarted.Text=lbl_sysIsStarted.Text+":"+"系统已启动，信息如下：";
                            lbl_startTime.Text=lbl_startTime.Text+":"+pros[i].StartTime.ToString("yyyy-MM-dd HH:mm:ss:fff");
                            lbl_isResponds.Text=lbl_isResponds.Text+":"+pros[i].Responding.ToString();
                            lbl_proThreadCount.Text=lbl_proThreadCount.Text+":"+pros[i].Threads.Count.ToString();
                            lbl_proLocation.Text=lbl_proLocation.Text+":"+pros[i].MainModule.FileName;
                        }));
                        //MessageBox.Show(txt_restartTimes.Text);
                        if(cbx_isListening.Checked==true) {
                            if(alreadyStartCount>Convert.ToInt32(txt_restartTimes.Text)) {
                                pros[i].Kill();
                                startCount=0;
                                Thread.Sleep(10000);
                            }
                        }

                        /*****************************************************************/
                    }
                } else {//程序未启动
                    Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff")+"SingbonICCard系统未启动或者未启用监听");
                    lbl_sysIsStarted.Text="系统未启动。";
                    if(cfg.openSystemRestart=="1") {
                        lbl_sysIsStarted.Text="系统未启动,已启用自动重启。";
                        if(startCount<=0) {
                            lbl_sysIsStarted.Text="系统未启动正在启动程序...";
                            //string cmd = @"SingbonICCard.exe";
                            //string output = "123456";
                            //RunCmd(cmd, out output);
                            System.Diagnostics.Process.Start("SingbonICCard.exe");
                            Thread.Sleep(20000);
                            startCount=startCount+1;
                        }
                        lbl_sysIsStarted.Text="请等待程序启动....";
                    }
                }
                Thread.Sleep(5000);
            }
        }

        #endregion 主线程

        private void btn_startListen_Click(object sender, EventArgs e) {
            if(txt_ExeName.Text=="") {
                MessageBox.Show("请输入exe文件名称");
                cbx_isListening.Checked=false;
                return;
            }
            btn_startListen.Enabled=false;
            btn_stopListen.Enabled=true;
            cbx_isListening.Enabled=false;
            cbx_alsoOpenMonitor.Enabled=false;
            lbl_restartTimes.Enabled=false;
            lbl_sysPwd.Enabled=false;
            label2.Enabled=false;
            txt_pwd.Enabled=false;
            txt_restartTimes.Enabled=false;
            txt_ExeName.Enabled=false;
            isListening=1;
            t=new Thread(new ThreadStart(ListenSingbon));
            t.Start();
        }

        private void btn_stopListen_Click(object sender, EventArgs e) {
            btn_startListen.Enabled=true;
            btn_stopListen.Enabled=false;
            isListening=0;
            startCount=0;
            lbl_sysAlreadyStartTimeCount.Text="启动时长：";
            lbl_sysIsStarted.Text="是否启动：";
            lbl_startTime.Text="启动时间：";
            lbl_isResponds.Text="是否响应：";
            lbl_proThreadCount.Text="进程线程个数：";
            lbl_proLocation.Text="进程所在目录：";
            cbx_isListening.Enabled=true;
            cbx_alsoOpenMonitor.Enabled=true;
            lbl_restartTimes.Enabled=true;
            lbl_sysPwd.Enabled=true;
            label2.Enabled=true;
            txt_pwd.Enabled=true;
            txt_restartTimes.Enabled=true;
            txt_ExeName.Enabled=true;
        }

        private void cbx_isListening_CheckedChanged(object sender, EventArgs e) {
            if(cbx_isListening.Checked) {
                if(txt_ExeName.Text=="") {
                    MessageBox.Show("请输入exe文件名称");
                    cbx_isListening.Checked=false;
                    return;
                }
                if(txt_pwd.Text=="") {
                    MessageBox.Show("请输入软件密码");
                    cbx_isListening.Checked=false;
                    return;
                }
                if(txt_restartTimes.Text=="") {
                    MessageBox.Show("请输入重启周期");
                    cbx_isListening.Checked=false;
                    return;
                }
                cbx_isListening.Text="当前状态：启用";
                lbl_restartTimes.Enabled=false;
                lbl_sysPwd.Enabled=false;
                label2.Enabled=false;
                txt_pwd.Enabled=false;
                txt_restartTimes.Enabled=false;
                txt_ExeName.Enabled=false;
                cbx_alsoOpenMonitor.Checked=true;
                cfg.SysPwd=txt_pwd.Text;
                cfg.openSystemRestart="1";
                cfg.alsoOpenMonitor="1";
                cfg.SaveConfig();
            } else {
                cbx_isListening.Text="当前状态：停用";
                lbl_restartTimes.Enabled=true;
                lbl_sysPwd.Enabled=true;
                label2.Enabled=true;
                txt_pwd.Enabled=true;
                txt_restartTimes.Enabled=true;
                txt_ExeName.Enabled=true;
                cbx_alsoOpenMonitor.Checked=false;
                cfg.openSystemRestart="0";
                cfg.alsoOpenMonitor="0";
                cfg.SaveConfig();
            }
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e) {
            if(cbx_alsoOpenMonitor.Checked) {
                cbx_alsoOpenMonitor.Text="当前状态：启用";
                cfg.alsoOpenMonitor="1";
                cfg.SaveConfig();
            } else {
                cbx_alsoOpenMonitor.Text="当前状态：停用";
                cfg.alsoOpenMonitor="0";
                cfg.SaveConfig();
            }
        }

        private void btn_exit_Click(object sender, EventArgs e) {
            Console.WriteLine("退出");
            System.Environment.Exit(0);
        }

        public static void RunCmd(string cmd, out string output) {
            cmd=cmd.Trim().TrimEnd('&')+"&exit";//说明：不管命令是否成功均执行exit命令，否则当调用ReadToEnd()方法时，会处于假死状态
            using(Process p = new Process()) {
                p.StartInfo.FileName="cmd.exe";
                p.StartInfo.UseShellExecute=false;        //是否使用操作系统shell启动
                p.StartInfo.RedirectStandardInput=true;   //接受来自调用程序的输入信息
                p.StartInfo.RedirectStandardOutput=true;  //由调用程序获取输出信息
                p.StartInfo.RedirectStandardError=true;   //重定向标准错误输出
                p.StartInfo.CreateNoWindow=true;          //不显示程序窗口
                p.Start();//启动程序
                //向cmd窗口写入命令
                p.StandardInput.WriteLine(cmd);
                p.StandardInput.AutoFlush=true;
                //获取cmd窗口的输出信息
                output=p.StandardOutput.ReadToEnd();
                p.WaitForExit();//等待程序执行完退出进程
                p.Close();
            }
        }

        /***********************************/

        /// 窗体关闭的单击事件
        private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
            e.Cancel=true;
            this.Hide();
            this.定时重启.ShowBalloonTip(500);
        }

        private void InitialTray() {
            //隐藏主窗体
            this.Hide();
            this.定时重启.Visible=true;
            //气泡显示的时间（单位是毫秒）
            this.定时重启.ShowBalloonTip(500);
            this.定时重启.MouseClick+=new System.Windows.Forms.MouseEventHandler(notifyIcon_MouseClick);
            //关于选项
            MenuItem about = new MenuItem("关于");
            //退出菜单项
            MenuItem exit = new MenuItem("退出");
            exit.Click+=new EventHandler(exit_Click);
            about.Click+=new EventHandler(about_Click);
            //注释的这一行与下一行的区别就是参数不同，setting这个参数是为了实现二级菜单
            MenuItem[] childen = new MenuItem[] { about, exit };
            this.定时重启.ContextMenu=new ContextMenu(childen);
            //窗体关闭时触发
            this.FormClosing+=new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
        }

        /// 鼠标单击
        private void notifyIcon_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e) {
            //鼠标左键单击
            if(e.Button==MouseButtons.Left) {
                //如果窗体是可见的，那么鼠标左击托盘区图标后，窗体为不可见
                if(this.Visible==false) {
                    this.Visible=true;
                    this.Activate();
                }
            }
        }

        /// 退出选项
        private void exit_Click(object sender, EventArgs e) {
            this.定时重启.Dispose();
            this.Dispose();
            this.Close();
            System.Environment.Exit(0);

        }

        //关于
        private void about_Click(object sender, EventArgs e) {
            MessageBox.Show("2018 新年好！");
        }

        /***************************************************/
    }
}